/*
 * BFXCommon.h
 *
 *  Created on: Jun 16, 2016
 *      Author: Lucifer
 */

#ifndef BFX_COMMON_H_
#define BFX_COMMON_H_

////////////////////////////////////////////////////////////////////////////////
/// Platform & compiler specification

#define PLATFORM_WINDOWS	0
#define PLATFORM_UNIX		1
#define PLATFORM_APPLE		2
#define PLATFORM_INTEL		3

// must be first (win 64 also define WIN32)
#if defined( _WIN64 )
#	define PLATFORM PLATFORM_WINDOWS
#elif defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 )
#	define PLATFORM PLATFORM_WINDOWS
#	define WIN_X86
#elif defined( __APPLE_CC__ )
#	define PLATFORM PLATFORM_APPLE
#elif defined( __INTEL_COMPILER )
#	define PLATFORM PLATFORM_INTEL
#else
#	define PLATFORM PLATFORM_UNIX
#endif

#define COMPILER_MICROSOFT 0
#define COMPILER_GNU       1
#define COMPILER_BORLAND   2
#define COMPILER_INTEL     3
#define COMPILER_CLANG     4

#ifdef _MSC_VER
#	define COMPILER COMPILER_MICROSOFT
#elif defined( __BORLANDC__ )
#	define COMPILER COMPILER_BORLAND
#elif defined( __INTEL_COMPILER )
#	define COMPILER COMPILER_INTEL
#elif defined(__clang__)
#	define COMPILER COMPILER_CLANG
#elif defined( __GNUC__ ) && !defined(__clang__)
#	define COMPILER COMPILER_GNU
#else
#	pragma error "FATAL ERROR: Unknown compiler."
#endif

////////////////////////////////////////////////////////////////////////////////
/// Helper macros

#if __cplusplus >= 201103L
#	ifndef _GNU_SOURCE
#		define _GNU_SOURCE
#	endif
#endif

#ifndef BFX_ASSERT
#	if defined(DEBUG) || defined(_DEBUG)
#		include <assert.h>
#		define BFX_ASSERT assert
#	else
#		define BFX_ASSERT
#	endif
#endif
#ifndef BFX_STATIC_ASSERT
#	if COMPILER == COMPILER_CLANG
#		define BFX_STATIC_ASSERT(exp, name) _Static_assert((exp), #name)
#	else
#		if __cplusplus < 201103L
#			define BFX_STATIC_ASSERT(exp, name)	{ char __dummy[(exp) ? 1 : -1]; (void)(__dummy); }
#		else
#			define BFX_STATIC_ASSERT(exp, name) static_assert((exp), #name)
#		endif
#	endif
#endif

#ifndef BFX_MAX
#	define BFX_MAX(a, b) (((a) > (b)) ? (a) : (b))
#	define BFX_MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif

////////////////////////////////////////////////////////////////////////////////
/// Differences of platforms

#include <stdio.h>
#if PLATFORM == PLATFORM_WINDOWS
#	define   WIN32_LEAN_AND_MEAN 
#	include <Windows.h>
#	define snprintf _snprintf
#	define vsnprintf _vsnprintf
#	define finite(X) _finite(X)
#endif

#endif /* BFX_COMMON_H_ */
